#include <stdio.h>
#include <stdlib.h>
#include "link_list.h"
#include "alg_errno.h"

struct _link_list{
    data_type data;
    struct _link_list *next;
};

typedef struct _link_list node;

/* 初始化句柄 */
int link_list_init(link_list **ctx)
{
    if(ctx == NULL) {
        return ALG_BAD_INPUT;
    }
    if(*ctx != NULL) {
        return ALG_BAD_INPUT;
    }

    *ctx = (node *)malloc(sizeof(node));
    
    (*ctx)->data = 0;
    (*ctx)->next = NULL;
    
    if(*ctx == NULL) {
        return ALG_MALLOC_FAIL;
    }

    return ALG_OK;
}

/* 头部插入一个节点 */
int link_list_add_head(link_list *ctx, data_type data)
{
    node *t = NULL;
    
    if(ctx == NULL) {
        return ALG_BAD_INPUT;
    }

    t = (node *)malloc(sizeof(node));
    t->data = data;
    t->next = ctx->next;

    ctx->next = t;

    return ALG_OK;
}

/* 尾部插入一个节点 */
int link_list_add_rear(link_list *ctx, data_type data)
{
    node *t = NULL, *p = NULL;

    if(ctx == NULL) {
        return ALG_BAD_INPUT;
    }

    t = (node *)malloc(sizeof(node));
    if(t == NULL) {
        return ALG_MALLOC_FAIL;
    }

    t->next = NULL;
    t->data = data;

    p = ctx;
    while(p->next != NULL) {
        p = p->next;
    }
    p->next = t;

    return ALG_OK;
}

/* 删除第一个为target元素的节点 */
int link_list_delete_first_target(link_list *ctx, data_type target)
{
    node *t = NULL;
    
    if(ctx == NULL) {
        return ALG_BAD_INPUT;
    }

    if(ctx->next == NULL) {
        return ALG_BAD_INPUT;
    }

    t = ctx;
    while(t->next != NULL) {
        if(t->next->data == target) {
            node *temp = t->next;
            t->next = temp->next;
            free(t);
            return ALG_OK;
        }
        t = t->next;
    }

    return ALG_NODE_NOT_EXIST;
}

/* 清空链表 */
int link_list_clean(link_list *ctx)
{
    node *t = NULL;

    if(ctx == NULL) {
        return ALG_BAD_INPUT;
    }

    if(ctx->next == NULL) {
        return ALG_OK;
    }

    t = ctx->next;
    while(t != NULL) {
        node *temp = t;
        t = t->next;
        free(temp);
    }

    ctx->next = NULL;

    return ALG_OK;
}

/* 打印链表 */
int link_list_show(link_list *ctx)
{
    node *t = NULL;

    if(ctx == NULL) {
        return ALG_BAD_INPUT;
    }
    if(ctx->next == NULL) {
        return ALG_BAD_INPUT;
    }

    t = ctx->next;

    printf("%d", t->data);
    t = t->next;

    while(t != NULL) {
        printf("->%d", t->data);
        t = t->next;
    }

    return ALG_OK;
}